# Type Check Plugin

import { SourceCode } from 'rspress/theme';

<SourceCode href="https://github.com/web-infra-dev/rsbuild/tree/main/packages/plugin-type-check" />

The Type Check plugin provides the ability to run TypeScript type checks in a separate process. The plugin internally integrates with [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin).

## Introduction

The type checking logic of `fork-ts-checker-webpack-plugin` is similar to the native `tsc` command of TypeScript. It automatically reads the configuration options from `tsconfig.json` and can also be modified via the configuration options provided by the Type Check plugin.

The behavior of the plugin differs in the development and production builds:

- During development builds, type errors do not block the build process. They are only logged in the terminal.
- During production builds, type errors cause the build to fail in order to ensure the stability of the production code.

## Quick Start

### Install Plugin

You can install the plugin using the following command:

import { PackageManagerTabs } from '@theme';

<PackageManagerTabs command="add @rsbuild/plugin-type-check -D" />

### Register Plugin

You can register the plugin in the `rsbuild.config.ts` file:

```ts title="rsbuild.config.ts"
import { pluginTypeCheck } from '@rsbuild/plugin-type-check';

export default {
  plugins: [pluginTypeCheck()],
};
```

### Configuring tsconfig.json

The Type Check plugin by default performs checks based on the `tsconfig.json` file in the root directory of the current project. Below is an example of a `tsconfig.json` file, which you can also adjust according to the needs of your project.

```json title="tsconfig.json"
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["DOM", "ES2020"],
    "module": "ESNext",
    "strict": true,
    "skipLibCheck": true,
    "isolatedModules": true,
    "resolveJsonModule": true,
    "moduleResolution": "bundler"
  },
  "include": ["src"]
}
```

Please note that the fields in `tsconfig.json` will not affect the compilation behavior and output of Rsbuild, but will only affect the results of type checking.

## Options

### enable

Whether to enable TypeScript type checking.

- **Type:** `boolean`
- **Default:** `true`
- **Example:**

Disable TypeScript type checking:

```js
pluginTypeCheck({
  enable: false,
});
```

Enable type checking only during production builds:

```js
pluginTypeCheck({
  enable: process.env.NODE_ENV === 'production',
});
```

Enable type checking only during development builds (it is not recommended to disable type checking during production builds, as it may reduce the stability of the production code):

```js
pluginTypeCheck({
  enable: process.env.NODE_ENV === 'development',
});
```

### forkTsCheckerOptions

To modify the options of `fork-ts-checker-webpack-plugin`, please refer to [fork-ts-checker-webpack-plugin - README](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#readme) to learn about available options.

- **Type:** `Object | Function`
- **Default:**

```ts
const defaultOptions = {
  typescript: {
    // set 'readonly' to avoid emitting tsbuildinfo,
    // as the generated tsbuildinfo will break fork-ts-checker
    mode: 'readonly',
    // enable build when using project reference
    build: useReference,
    // avoid OOM issue
    memoryLimit: 8192,
    // use tsconfig of user project
    configFile: tsconfigPath,
    // use typescript of user project
    typescriptPath: require.resolve('typescript'),
  },
  issue: {
    // ignore types errors from node_modules
    exclude: [({ file = '' }) => /[\\/]node_modules[\\/]/.test(file)],
  },
  logger: {
    log() {
      // do nothing
      // we only want to display error messages
    },
    error(message: string) {
      console.error(message.replace(/ERROR/g, 'Type Error'));
    },
  },
};
```

#### Object Type

When the value of `forkTsCheckerOptions` is an object, it will be deeply merged with the default configuration.

```ts
pluginTypeCheck({
  forkTsCheckerOptions: {
    issue: {
      exclude: [({ file = '' }) => /[\\/]some-folder[\\/]/.test(file)],
    },
  },
});
```

#### Function Type

When the value of `forkTsCheckerOptions` is a function, the default configuration will be passed as the first argument. You can directly modify the configuration object or return an object as the final configuration.

```ts
pluginTypeCheck({
  forkTsCheckerOptions(options) {
    options.async = false;
    return options;
  },
});
```

## Notes

- If you have enabled `ts-loader` in your project and manually configured `compileOnly: false`, please disable the Type Check plugin to avoid duplicate type checking.
- Some errors will be displayed as warnings in IDEs such as VS Code, but they will still be displayed as errors in the `fork-ts-checker-webpack-plugin` check. For details, please refer to: [Why are some errors reported as warnings?](https://code.visualstudio.com/docs/typescript/typescript-compiling#_why-are-some-errors-reported-as-warnings).

## Performance Optimization

Type checking has a significant performance overhead. You can refer to the [Performance Guide](https://github.com/microsoft/TypeScript/wiki/Performance) in the official TypeScript documentation for performance optimization.

For example, properly configuring the `include` and `exclude` scopes in `tsconfig.json` can significantly reduce unnecessary type checking and improve TypeScript performance:

```json title="tsconfig.json"
{
  "include": ["src"],
  "exclude": ["**/node_modules", "**/.*/"]
}
```

## Vue Components

`fork-ts-checker-webpack-plugin` does not support checking TypeScript code in `.vue` components. You can check for type issues in `.vue` files in the following ways:

1. Install the [vue-tsc](https://github.com/vuejs/language-tools/tree/master/packages/tsc) package, which provides the ability to check types in `.vue` files.

<PackageManagerTabs command="add vue-tsc -D" />

2. Add the `vue-tsc --noEmit` command to the `build` script in package.json:

```diff title="package.json"
{
  "scripts": {
-   "build": "rsbuild build"
+   "build": "vue-tsc --noEmit && rsbuild build"
  }
}
```

3. Since the production build uses `vue-tsc` for type checking, you can disable the Type Check plugin in the production build to avoid redundant checks.

```js
pluginTypeCheck({
  enable: process.env.NODE_ENV === 'development',
});
```
